package com.wetool.wechat.service;

import com.wetool.common.model.Message;
import com.wetool.common.model.Result;
import com.wetool.common.wechat.PaymentMessage;
import com.wetool.common.wechat.ReviewMessage;
import com.wetool.common.wechat.WechatResult;
import com.wetool.wechat.entity.WechatAccountRelation;
import com.wetool.wechat.entity.WechatMerchantRelation;
import com.wetool.wechat.feign.WechatOfficialFeignClient;
import com.wetool.wechat.jpa.WechatAccountRelationRepo;
import com.wetool.wechat.jpa.WechatMerchantRelationRepo;
import com.wetool.wechat.model.QrCodeRequest;
import com.wetool.wechat.model.SceneType;
import com.wetool.wechat.model.SceneValue;
import com.wetool.wechat.model.official.AccessTokenResponse;
import com.wetool.wechat.model.official.ErrorMessage;
import com.wetool.wechat.model.official.OfficialUserInfo;
import com.wetool.wechat.model.official.menu.*;
import com.wetool.wechat.model.official.template.MessageData;
import com.wetool.wechat.model.official.template.MessageResponse;
import com.wetool.wechat.model.official.template.TemplateMessageRequest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class WechatOfficialService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WechatOfficialService.class);

    private static final String access_token = "ACCESS_TOKEN";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private WechatOfficialFeignClient wechatOfficialFeignClient;

    @Autowired
    private WechatAccountRelationRepo wechatAccountRelationRepo;

    @Autowired
    private WechatOAuthService wechatOAuthService;

    @Autowired
    private WechatMerchantRelationRepo wechatMerchantRelationRepo;

    @Value("${wechat.official-account.appId}")
    private String appId;

    @Value("${wechat.official-account.appSecret}")
    private String appSecrut;

    @Value("${wechat.message.review-template.id}")
    private String reviewTemplateId;

    @Value("${wechat.message.payment-template.id}")
    private String paymentTemplateId;


    /**
     * 刷新公众号平台accessToken
     */
    private AccessTokenResponse refreshAccessToken() {
        AccessTokenResponse accessTokenResponse = this.wechatOfficialFeignClient.accessToken(appId, appSecrut);
        return accessTokenResponse;
    }

    /**
     * 获取微信公众号平台accessToken,若失效则刷新
     *
     * @return
     */
    public String getAccessToken() {

        String token = redisTemplate.opsForValue().get(access_token);

        if (StringUtils.isEmpty(token)) {
            LOGGER.info("当前token不存在");
            AccessTokenResponse accessTokenResponse = this.refreshAccessToken();
            redisTemplate.boundValueOps(access_token).set(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn(), TimeUnit.SECONDS);
            token = accessTokenResponse.getAccessToken();
            LOGGER.info("刷新微信公众号accessToken:{}", accessTokenResponse);
        }
        return token;
    }

    /**
     * 通过公众号openId获取unionId
     *
     * @return
     */
    public String getUnionIdByOpenId(String openId) {
        OfficialUserInfo userInfo = this.wechatOfficialFeignClient.userInfo(this.getAccessToken(), openId);
        return userInfo.getUnionId();
    }


    public Message<?> sendMessage(ReviewMessage message, long userId) {
        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByUserId(userId);

        Map<String, MessageData> data = new HashMap<>();
        data.put("first", new MessageData(message.getContent()));
        data.put("keyword1", new MessageData(message.getStatus()));
        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(message.getDate());
        data.put("keyword2", new MessageData(dateStr));
        data.put("remark", new MessageData(message.getRemark()));

        TemplateMessageRequest templateMessageRequest = new TemplateMessageRequest();
        templateMessageRequest.setOpenId(accountRelation.getOfficialOpenId());
        templateMessageRequest.setTemplateId(this.reviewTemplateId);
        templateMessageRequest.setData(data);
        return this.sendMessage(templateMessageRequest);
    }

    public Message<?> sendMessage(PaymentMessage message, String openId) {

//        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByUserId(openId);

        Map<String, MessageData> data = new HashMap<>();
        data.put("first", new MessageData(message.getDescription()));
        data.put("keyword1", new MessageData(message.getShopName()));
        data.put("keyword2", new MessageData(message.getOrderNo()));
        data.put("keyword3", new MessageData(message.getAmount()));
        data.put("keyword4", new MessageData(message.getPayUser()));
        data.put("keyword5", new MessageData(message.getPayMethod()));
        data.put("remark", new MessageData(message.getRemark()));

        TemplateMessageRequest templateMessageRequest = new TemplateMessageRequest();
        templateMessageRequest.setOpenId(openId);
        templateMessageRequest.setTemplateId(this.paymentTemplateId);
        templateMessageRequest.setData(data);
        return this.sendMessage(templateMessageRequest);
    }

    /**
     * 向指定用户发送模板消息
     *
     * @return
     */
    public Message<?> sendMessage(TemplateMessageRequest request) {

        MessageResponse responseEntity = this.wechatOfficialFeignClient.sendMessage(this.getAccessToken(), request);

        if (responseEntity == null) {
            LOGGER.error("微信模板消息发送失败，Feign调用微信发送接口失败");
            return new Message<>(WechatResult.MESSAGE_SEND_FAILED);
        }

        if (responseEntity.getErrcode().equals("0") && responseEntity.getErrmsg().equals("ok")) {
            return new Message<>(Result.SUCCESS, "微信消息发送成功");
        } else {
            LOGGER.error("微信消息发送失败,openId:【{}】,errorCode:【{}】,errorMsg:【{}】", request.getOpenId(), responseEntity.getErrcode(), responseEntity.getErrmsg());
            return new Message<>(WechatResult.MESSAGE_SEND_FAILED);
        }
    }

    /**
     * 创建二维码
     *
     * @return
     */
    public Message<?> createQrCode() {
        String accessToken = this.getAccessToken();
        Object response = this.wechatOfficialFeignClient.createQrCode(accessToken, new QrCodeRequest(600, SceneType.QR_STR_SCENE, SceneValue.REGISTER_SERVICE_PROVIDER.getName()));
        return new Message<>(Result.SUCCESS, response);
    }

    /**
     * @param merchantId
     * @return
     */
    public Message<?> createQrCode(Long merchantId) {

        String accessToken = this.getAccessToken();
        Map<String, Object> response = (Map<String, Object>) this.wechatOfficialFeignClient.createQrCode(accessToken, new QrCodeRequest(600, SceneType.QR_STR_SCENE, SceneValue.REGISTER_MERCHANT.getName()));

        if (response == null) {
            return new Message<>(Result.ERROR, "二维码获取失败");
        }
        
        if(merchantId != null) {
        	LOGGER.debug("商家{}注册关注公众号", merchantId);
        	String ticket = (String) response.get("ticket");
            WechatMerchantRelation relation = this.wechatMerchantRelationRepo.findOne(merchantId);
            if (relation == null) {
                this.wechatMerchantRelationRepo.save(new WechatMerchantRelation(merchantId, ticket));
            } else {
                relation.setTicket(ticket);
                this.wechatMerchantRelationRepo.save(relation);
            }
        }
        
        return new Message<>(Result.SUCCESS, response);
    }

    public Message<?> settingCustomMenu() {

        String accessToken = this.getAccessToken();

        MenuGroup menuGroup = new MenuGroup();

        MenuButton menuButton1 = new MenuButton(ButtonType.VIEW, "超市入口", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000003&idx=1&sn=55a85775291ebea238e7bf193a49ec5a&chksm=7bf59f2a4c82163cd1cffa7520ab12fb93c3f7b148931be1144c48bdc1dd8ac381e79d8ebcd8#rd");
        menuGroup.addButton(menuButton1);


        MenuButton menuButton2 = new MenuButton(ButtonType.CLICK, ButtonKey.normal_button, "管理平台");
        menuButton2.addButton(new SubMenuButton(ButtonType.VIEW, "便利店", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000005&idx=1&sn=7912f02f49fa8067734d7db7e2cfeb70&chksm=7bf59f2c4c82163a548a2539f8c2f229f791e5d0ca06e73dbdf037e1517663945a7b1114ff20#rd"));
        menuButton2.addButton(new SubMenuButton(ButtonType.VIEW, "品牌商", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000011&idx=1&sn=78d510932e757a7ba74d365d336732b7&chksm=7bf59f224c8216345a2191acae6e66a90ee72164bb7d25005c387d9ad88f8953407e10420e13#rd"));
        menuButton2.addButton(new SubMenuButton(ButtonType.VIEW, "供货商", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000013&idx=1&sn=3fc6003a9d1b4c885e065f5a19241a52&chksm=7bf59f244c82163285d57a90d913f02b0fdf51311ac4a650c9f87ca4e57d7461edd30212f730#rd"));
        menuGroup.addButton(menuButton2);


        MenuButton menuButton3 = new MenuButton(ButtonType.CLICK, ButtonKey.normal_button, "关于我们");
        menuButton3.addButton(new SubMenuButton(ButtonType.VIEW, "公司简介", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000015&idx=1&sn=eb0ee0ac5cd05cae04e5b140079a6efa&chksm=7bf59f264c821630620a196337c8b1825ec9682307d8622a673ebf1bd282b8d457bf56c526fb#rd"));
        menuButton3.addButton(new SubMenuButton(ButtonType.VIEW, "产品介绍", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000018&idx=1&sn=ea07ee80752851f2b65d306652bfb7d4&chksm=7bf59f3b4c82162db64f0b620cfd3c41713e340da201cd0298a38fff2f6494f56e65ba8513b7#rd"));
        menuButton3.addButton(new SubMenuButton(ButtonType.VIEW, "合作加盟", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000020&idx=1&sn=63a2436463842659d8b9a48e8eb35f36&chksm=7bf59f3d4c82162b9ad3316335757a4fdf6c6c95a4622318891187cc7cbe28e94771f5d3da93#rd"));
        menuButton3.addButton(new SubMenuButton(ButtonType.VIEW, "微兔历程", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000024&idx=1&sn=ef8df9c660162010d2c30e100b44a019&chksm=7bf59f314c821627f36fc2d6ddd033d44c0a3e6cecbab715184576b4a6a6ee95b0b0f5751aec#rd"));
        menuButton3.addButton(new SubMenuButton(ButtonType.VIEW, "求才若渴", "http://mp.weixin.qq.com/s?__biz=MzU1MzMwNjk1MA==&mid=100000044&idx=1&sn=73d63ff0e9430dbd32e2508df083ac28&chksm=7bf59f054c821613e02ea09927727730c408e0ba35895ef8549a7c324b6b07fbf834d7c754fd#rd"));
        menuGroup.addButton(menuButton3);


//        dtoList.forEach(menuDto -> menuGroup.addButton(menuDto.to()));

        ErrorMessage result = this.wechatOfficialFeignClient.createMenu(accessToken, menuGroup);

        return new Message<>(Result.SUCCESS, result);
    }

}
